# coding=utf-8

import pexpect
import multiprocessing
from pexpect import *

from app.modules.common.pipelines import *
from app.modules.common.tasks import *
from app.modules.common.tasks import TaskExcecuteError, TaskParamsError
from app.modules.common.utils import *
from app.modules.database.pipelines import BaseTask

log = logging.getLogger(__name__)

lock = multiprocessing.Lock()


class InitImportOraclePipeLine(Pipeline):
    def __init__(self, name, group=None, timeout=7200, **kwargs):
        Pipeline.__init__(self, name, group=group, timeout=timeout, **kwargs)

        self.add_task(CheckOracleImportParams())
        self.add_task(CheckOracleProcessTask())
        self.add_task(CleanTempPathTask())
        self.add_task(CopyDumpFileTask())
        self.add_task(UnzipDumpFileTask())
        self.add_task(InitImportOracleTask())
        self.add_task(AfterImportTask())
        self.add_task(UnlockOracleUserTask())
        self.add_task(CleanTempPathTask())

    def _before_execute(self):
        log.info('start execute _before_execute')
        self.get_log(log).do_up()
        log.info('end execute _before_execute')

    def _after_execute(self):
        self.get_log(log).do_down()


class IncrementalImportOraclePipeLine(Pipeline):
    def __init__(self, name, group=None, timeout=7200, **kwargs):
        Pipeline.__init__(self, name, group=group, timeout=timeout, **kwargs)

        self.add_task(CheckOracleImportParams())
        self.add_task(CheckOracleProcessTask())
        self.add_task(CleanTempPathTask())
        self.add_task(CopyDumpFileTask())
        self.add_task(UnzipDumpFileTask())
        self.add_task(IncrementalImportOracleTask())
        self.add_task(AfterImportTask())

    def _before_execute(self):
        log.info('start execute _before_execute')
        self.get_log(log).do_up()
        log.info('end execute _before_execute')

    def _after_execute(self):
        self.get_log(log).do_down()


class CheckOracleImportParams(BaseTask):
    def __init__(self):
        Task.__init__(self, 'CheckImportParams')

    def __do_execute__(self, params={'username': None,
                                     'password': None,
                                     'temp_path': None,
                                     'dump_path': None,
                                     'db_name': None,
                                     'clean_script_path': None,
                                     'tablespace': None,
                                     'source_username': None,
                                     'source_tablespace': None,
                                     'after_imp_sql_files': None,
                                     'truncate_tables_filename': None
                                     }):
        log_proxy = self.get_log(log)
        log_proxy.info('********************************************************')
        log_proxy.info("=======> CheckImportParams:Entered execute()")

        error_message=[]
        param_valid = True
        if not self.param_exists('username', params):
            param_valid = False
            error_message.append('params[username] must not empty')
        else:
            log_proxy.info("=======> params[username] is %s", params['username'])

        if not self.param_exists('password', params):
            param_valid = False
            error_message.append('params[password] must not empty')
        else:
            log_proxy.info("=======> params[password] is %s", params['password'])

        if not self.param_exists('temp_path', params):
            param_valid = False
            error_message.append('params[temp_path] must not empty')
        else:
            log_proxy.info("=======> params[temp_path] is %s", params['temp_path'])

        if not self.param_exists('dump_path', params):
            param_valid = False
            error_message.append('params[dump_path] must not empty')
        else:
            log_proxy.info("=======> params[dump_path] is %s", params['dump_path'])

        if not self.param_exists('db_name', params):
            params['db_name'] = params['username']
        log_proxy.info("=======> params[db_name] is %s", params['db_name'])

        if not self.param_exists('tablespace', params):
            params['tablespace'] = params['username']
            log_proxy.info("=======> params[tablespace] is empty, set to the username : %s", params['tablespace'])
        else:
            log_proxy.info("=======> params[tablespace] is %s", params['tablespace'])

        if not self.param_exists('source_username', params):
            params['source_username'] = 'adempiere'
        log_proxy.info('=======> source username is : %s', params['source_username'])

        if not self.param_exists('source_tablespace', params):
            params['source_tablespace'] = 'TS_ADEMPIERE'
        log_proxy.info('=======> source tablespace is : %s', params['source_tablespace'])

        if param_valid and not os.path.exists(params['dump_path']):
            param_valid = False
            error_message.append('not found dump path[%s].' % params['dump_path'])

        if param_valid and not os.path.exists(params['temp_path']):
            self.create_path(params['temp_path'])

        if not param_valid:
            log_proxy.error("******** %s", error_message)
            raise TaskParamsError(error_message)

        log_proxy.info("=======> CheckImportParams:Exit execute()")


class CheckOracleProcessTask(Task):
    def __init__(self):
        Task.__init__(self, 'CheckOracleProcess')

    def __do_execute__(self, params={}):
        log_proxy = self.get_log(log)
        log_proxy.info('********************************************************')
        log_proxy.info("=======> CheckOracleProcess:Entered execute()")

        with lock:
            try:
                sh = '/bin/bash -c "ps -ef | grep ora_ | grep -v grep | wc -l"'
                log_proxy.info('=======> start check oracle proces, shell : %s', sh)
                output, status = run(sh, withexitstatus=1, logfile=log_proxy)
                log_proxy.info('=======> shell status: %s, output: %s', status, output)

                if status == 0 and int(output) != 0:
                    log_proxy.info('=======> check oracle process success.')
                else:
                    log_proxy.info('=======> Oracle process does not exist')
                    log_proxy.info('=======> try start oracle')
                    log_proxy.info('=======> su - oracle')
                    sqlplus = pexpect.spawn('su - oracle', timeout=300)
                    sqlplus.logfile = log_proxy
                    log_proxy.info('=======> lsnrctl start')
                    sqlplus.sendline('lsnrctl start')
                    sqlplus.expect('$', timeout=300)
                    sqlplus.sendline('export ORACLE_SID=orcldb')
                    sqlplus.expect('$', timeout=60)
                    log_proxy.info('=======> sqlplus / as sysdba')
                    sqlplus.sendline('sqlplus / as sysdba')
                    sqlplus.expect('SQL>')
                    log_proxy.info('=======> set head off')
                    sqlplus.sendline('set head off')
                    sqlplus.expect('SQL>')
                    log_proxy.info('=======> set feedback off')
                    sqlplus.sendline('set feedback off')
                    sqlplus.expect('SQL>')
                    log_proxy.info('=======> startup')
                    sqlplus.sendline('startup')
                    sqlplus.expect('SQL>', timeout=None)
                    sqlplus.sendline('exit')
                    sqlplus.close()

                    log_proxy.info('=======> recheck oracle process, shell : %s', sh)
                    output, status = run(sh, withexitstatus=1, logfile=log_proxy)
                    log_proxy.info('=======> shell status: %s, output: %s', status, output)

                    if status == 0 and int(output) != 0:
                        log_proxy.info('=======> check oracle process success.')
                    else:
                        raise TaskExcecuteError('start oracle error')

            except BaseException, e:
                log_proxy.error('=======> ' + e.message)
                raise TaskExcecuteError('execute shell failure, cause: %s.' % e.message)

                log_proxy.info("=======> CheckOracleProcess:Exit execute()")


class CleanTempPathTask(BaseTask):

    def __init__(self):
        Task.__init__(self, 'cleanTempPathTask')

    def __do_execute__(self, params={}):
        log_proxy = self.get_log(log)
        log_proxy.info('********************************************************')
        log_proxy.info("=======> cleanTempPathTask:Entered execute()")

        path = '%s/%s' % (params['temp_path'], params['db_name'])
        self.create_path(path)

        log_proxy.info('********************************************************')
        files_path = '%s/*.zip %s/import.log %s/*.dmp %s/*.sql %s/*.txt' % (path, path, path, path, path)

        self.remove_files(files_path)

        log_proxy.info("=======> cleanTempPathTask:Exit execute()")


class CopyDumpFileTask(Task):

    def __init__(self):
        Task.__init__(self, 'CopyDumpFileTask')

    def __do_execute__(self, params={}):
        log_proxy = self.get_log(log)
        log_proxy.info('********************************************************')
        log_proxy.info("=======> CopyDumpFileTask:Entered execute()")
        path = '%s/%s' % (params['temp_path'], params['db_name'])
        sh = '/bin/bash -c "cp %s/* %s"' % (params['dump_path'], path)

        log_proxy.info('=======> start execute shell : %s', sh)
        try:
            output, status = run(sh, withexitstatus=1, timeout=300, logfile=log_proxy)
            log_proxy.info('=======> shell status: %s, output: %s', status, output)
        except BaseException, e:
            log_proxy.error('=======> ' + e.message)
            raise TaskExcecuteError('execute shell failure, cause: %s.' % e.message)
        log_proxy.info('=======> end execute shell')

        if (status == 0) or (not status):
            log_proxy.info('=======> copy dump file success.')
        else:
            raise TaskExcecuteError('copy dump file failure.')

        log_proxy.info("=======> CopyDumpFileTask:Exit execute()")


class UnzipDumpFileTask(Task):

    def __init__(self):
        Task.__init__(self, 'UnzipDumpFileTask')

    def __do_execute__(self, params={}):
        log_proxy = self.get_log(log)
        log_proxy.info('********************************************************')
        log_proxy.info("=======> UnzipDumpFileTask:Entered execute()")
        path = '%s/%s' % (params['temp_path'], params['db_name'])
        files = os.listdir(path)
        if len(files) == 0:
            log_proxy.error('dump file not exists')

        dump_zip = None
        for filename in files:
            if filename.endswith('.zip'):
                dump_zip = filename

        if not dump_zip:
            log_proxy.error('=======> Dump compressed file does not exist')
            raise TaskExcecuteError('Dump compressed file does not exist')

        params['import_dump_name'] = str(dump_zip).split('.zip')[0]
        log_proxy.info("---------->dump name %s", params['import_dump_name'])

        sh = '/bin/bash -c "unzip -o %s/%s -d %s"' % (path, dump_zip, path)

        log_proxy.info('=======> start unzip, shell : %s', sh)
        try:
            output, status = run(sh, withexitstatus=1, timeout=600, logfile=log_proxy)
            log_proxy.info('=======> shell status: %s, output: %s', status, output)

            if status != 0:
                raise TaskExcecuteError('upzip dump file failure.')
            else:
                log_proxy.info('=======> upzip dump file success.')
        except BaseException, e:
            log_proxy.error('=======> ' + e.message)
            raise TaskExcecuteError('execute shell failure, cause: %s.' % e.message)

        sh = '/bin/bash -c "rm -f %s/%s"' % (path, dump_zip)

        log_proxy.info('=======> start clean dump zip, shell : %s', sh)
        try:
            output, status = run(sh, withexitstatus=1, logfile=log_proxy)
            log_proxy.info('=======> shell status: %s, output: %s', status, output)

            if (status == 0) or (not status):
                log_proxy.info('=======> clean dump zip success.')
            else:
                raise TaskExcecuteError('clean dump zip failure.')
        except BaseException, e:
            log_proxy.error('=======> ' + e.message)
            raise TaskExcecuteError('execute shell failure, cause: %s.' % e.message)

        sh = '/bin/bash -c "chmod -R 777 %s"' % path
        log_proxy.info('=======> start execute shell : %s', sh)
        try:
            output, status = run(sh, withexitstatus=1, logfile=log_proxy)
            log_proxy.info('=======> shell status: %s, output: %s', status, output)
        except BaseException, e:
            log_proxy.error('=======> ' + e.message)
            raise TaskExcecuteError('execute shell failure, cause: %s.' % e.message)
        log_proxy.info('=======> end execute shell')

        if status != 0:
            raise TaskExcecuteError('chmod 777 path[%s] failure.', path)
        else:
            log_proxy.info('=======> chmod 777 path[%s] success.', path)

        log_proxy.info("=======> UnzipDumpFileTask:Exit execute()")


class InitImportOracleTask(Task):
    def __init__(self):
        Task.__init__(self, 'InitImportOracleTask')

    def replace_invalidate_chars(self, temp_path, username, regex):
        log_proxy = self.get_log(log)
        sh = '/bin/bash -c "sed -i \'%s\' %s/%s_disconnect.sql"' % (regex, temp_path, username)
        log_proxy.info('=======> start Replace invalid character, shell : %s', sh)
        try:
            output, status = run(sh, withexitstatus=1, logfile=log_proxy)
            log_proxy.info('=======> shell status: %s, output: %s', status, output)

            if status != 0:
                raise TaskExcecuteError('Replace invalid character failure.')
            else:
                log_proxy.info('=======> Replace invalid character success.')
        except BaseException, e:
            log_proxy.error('=======> ' + e.message)
            raise TaskExcecuteError('execute shell failure, cause: %s.' % e.message)

    def __do_execute__(self, params={}):
        log_proxy = self.get_log(log)
        log_proxy.info('********************************************************')
        log_proxy.info("=======> InitImportOracleTask:Entered execute()")

        db_name = params['db_name']
        temp_path = '%s/%s' % (params['temp_path'], params['db_name'])
        username = str(params['username']).upper()
        password = params['password']
        tablespace = params['tablespace']
        dump_path_name = username + '_DUMP_PATH'
        source_username = params['source_username']
        source_tablespace = params['source_tablespace']
        try:
            sqlplus = pexpect.spawn('su - oracle', timeout=60)
            sqlplus.logfile = log_proxy
            sqlplus.expect('$')
            sqlplus.sendline('sqlplus / as sysdba')
            sqlplus.expect('SQL>')
            sqlplus.sendline('set head off')
            sqlplus.expect('SQL>')
            sqlplus.sendline('set feedback off')
            sqlplus.expect('SQL>')

            sqlplus.sendline('SELECT USERNAME || \'_\' FROM ALL_USERS where USERNAME = \'%s\';' % username)
            index = sqlplus.expect([username + '_', pexpect.TIMEOUT], timeout=30)
            log_proxy.info('=====> index : %s', sqlplus.before)

            log_proxy.info('=====> index : %s', index)
            if index == 0:
                sqlplus.sendline('alter user %s account lock;' % username)
                sqlplus.expect('SQL>')
                sqlplus.sendline('spool %s/%s_disconnect.sql;' % (temp_path, username))
                sqlplus.sendline('select \'alter system kill session \'\'\' || sid ||\',\'||serial#||\'\'\' immediate;\' from v$session where username = UPPER(\'%s\');' % username)
                sqlplus.expect('SQL>')
                sqlplus.sendline('spool off')
                sqlplus.expect('SQL>')

                self.replace_invalidate_chars(temp_path, username, 's/SQL>.*//g')
                self.replace_invalidate_chars(temp_path, username, 's/new\s\{3\}.*//g')
                self.replace_invalidate_chars(temp_path, username, 's/old\s\{3\}.*//g')

                sqlplus.sendline('@%s/%s_disconnect.sql;' % (temp_path, username))
                sqlplus.expect('SQL>', timeout=1800)

            elif index == 1:
                log_proxy.info('user[%s] not exists.', username)

            sqlplus.sendline('DROP USER %s CASCADE;' % username)
            sqlplus.expect('SQL>', timeout=1800)

            sqlplus.sendline('DROP TABLESPACE %s INCLUDING CONTENTS AND DATAFILES;' % tablespace)
            sqlplus.expect('SQL>', timeout=1800)

            sqlplus.sendline(
                'create tablespace %s datafile \'/u01/app/oracle/oradata/orcldb/%s\' size 400M autoextend on next 10m maxsize unlimited;' % (
                tablespace, tablespace))
            sqlplus.expect('SQL>', timeout=1800)

            sqlplus.sendline('CREATE USER %s IDENTIFIED BY %s default tablespace %s account unlock;' % (username,
                                                                                                        password,
                                                                                                        tablespace))
            sqlplus.expect('SQL>', timeout=1800)

            sqlplus.sendline('GRANT CONNECT,RESOURCE,DBA,UNLIMITED TABLESPACE,CREATE TABLE TO %s;' % username)
            sqlplus.expect('SQL>', timeout=1800)

            sqlplus.sendline('ALTER USER %s DEFAULT ROLE CONNECT, RESOURCE, DBA;' % username)
            sqlplus.expect('SQL>', timeout=1800)

            sqlplus.sendline('grant READ, WRITE ON directory erpdump TO %s;' % username)
            sqlplus.expect('SQL>', timeout=1800)

            sqlplus.sendline('grant create any job to %s;' % username)
            sqlplus.expect('SQL>', timeout=1800)

            sqlplus.sendline('DROP DIRECTORY %s;' % dump_path_name)
            sqlplus.expect('SQL>', timeout=1800)

            sqlplus.sendline('create directory %s as \'%s\';' % (dump_path_name, temp_path))
            sqlplus.expect('SQL>', timeout=1800)

            sqlplus.sendline('grant read,write on directory %s to %s;' % (dump_path_name, username))
            sqlplus.expect('SQL>', timeout=1800)

            sqlplus.sendline('alter user %s account unlock;' % username)
            sqlplus.expect('SQL>', timeout=1800)

            sqlplus.sendcontrol('d')
            sqlplus.expect('$')

            remap = 'remap_schema=%s:%s remap_tablespace=%s:%s' % (source_username,
                                                                   username,
                                                                   source_tablespace,
                                                                   tablespace)

            # 只导入oracle表结构
            # sh = 'impdp %s/%s dumpfile=%s.dmp DIRECTORY=%s %s CONTENT=METADATA_ONLY' % (username,
            sh = 'impdp %s/%s dumpfile=%s.dmp DIRECTORY=%s %s ' % (username,
                                                                  password,
                                                                  params['import_dump_name'],
                                                                  dump_path_name,
                                                                  remap)
            log_proxy.info('======> Start execute oracle import : %s', sh)

            sqlplus.sendline(sh)

            index = sqlplus.expect(['Job "%s"."(.*)" completed with' % username, pexpect.EOF], timeout=None)
            if index == 0:
                log_proxy.info(u'<><><><><><><>oracle数据导入正常结束')
            elif index == 1:
                log_proxy.info(u'<><><><><><><>oracle数据导入shell执行程序数据流结束')
                log_proxy.info(u'<><><><><><><>oracle数据导入异常结束')
                raise TaskExcecuteError('oracle import error.')

            log_proxy.info('======> End execute oracle import ')
            time.sleep(5)
            sqlplus.close()

        except BaseException, e:
            log_proxy.error('=======> ' + e.message)
            raise TaskExcecuteError('execute shell failure, cause: %s.' % e.message)

        log_proxy.info("=======> InitOracleUserTask:Exit execute()")


class IncrementalImportOracleTask(Task):
    def __init__(self):
        Task.__init__(self, 'IncrementalImportOracleTask')

    def replace_invalidate_chars(self, temp_path, username, regex):
        log_proxy = self.get_log(log)
        sh = '/bin/bash -c "sed -i \'%s\' %s/%s_disconnect.sql"' % (regex, temp_path, username)
        log_proxy.info('=======> start Replace invalid character, shell : %s', sh)
        try:
            output, status = run(sh, withexitstatus=1, logfile=log_proxy)
            log_proxy.info('=======> shell status: %s, output: %s', status, output)

            if status != 0:
                raise TaskExcecuteError('Replace invalid character failure.')
            else:
                log_proxy.info('=======> Replace invalid character success.')
        except BaseException, e:
            log_proxy.error('=======> ' + e.message)
            raise TaskExcecuteError('execute shell failure, cause: %s.' % e.message)

    def replace_username_for_tables(self, params):
        log_proxy = self.get_log(log)
        log_proxy.info('=======> Start Replace the user name for the table to be trancate')

        temp_path = '%s/%s' % (params['temp_path'], params['db_name'])
        filename = temp_path + '/tables.txt'
        tp_filename = temp_path + '/drop_tables.sql';
        source_username = params['source_username']
        username = params['username']

        if 'truncate_tables_filename' in params.keys():
            filename = temp_path + '/' + params['truncate_tables_filename']

        if os.path.exists(filename) and os.path.isfile(filename):
            try:
                cmd = pexpect.spawn('su - oracle', timeout=60)
                cmd.logfile = log_proxy
                tbs = open(filename)
                lines = tbs.readlines()
                fp = open(tp_filename, 'w')
                for line in lines:
                    line = line.strip().replace(source_username+'.', username+'.')
                    fp.write('drop table %s cascade constraints;\r\n' % line)
                fp.close()
                tbs.close()
                cmd.close()
                log_proxy.info('=======> End Replace the user name for the table to be trancate')
                return tp_filename
            except BaseException, e:
                log_proxy.error('=======> ' + e.message)
                raise TaskExcecuteError('execute shell failure, cause: %s.' % e.message)
        else:
            log_proxy.info('=======> End Replace the username for the table to be trancate,There is no need for tables\'s truncate,')
            return None

    def __do_execute__(self, params={}):
        log_proxy = self.get_log(log)
        log_proxy.info('********************************************************')
        log_proxy.info("=======> InitOracleUserTask:Entered execute()")

        db_name = params['db_name']
        temp_path = '%s/%s' % (params['temp_path'], params['db_name'])
        username = str(params['username']).upper()
        password = params['password']
        tablespace = params['tablespace']
        dump_path_name = username + '_dump_path'
        source_username = params['source_username']
        source_tablespace = params['source_tablespace']
        try:
            truncate_file = self.replace_username_for_tables(params=params)

            sqlplus = pexpect.spawn('su - oracle', timeout=1800)
            sqlplus.logfile = log_proxy
            sqlplus.expect('$')
            sqlplus.sendline('sqlplus / as sysdba')
            sqlplus.expect('SQL>')
            sqlplus.sendline('set head off')
            sqlplus.expect('SQL>')
            sqlplus.sendline('set feedback off')
            sqlplus.expect('SQL>')

            sqlplus.sendline('SELECT USERNAME || \'_\' FROM ALL_USERS where USERNAME = \'%s\';' % username)
            index = sqlplus.expect([username + '_', pexpect.TIMEOUT], timeout=1800)
            log_proxy.info('=====> index : %s', sqlplus.before)

            log_proxy.info('=====> index : %s', index)
            if index == 0:
                sqlplus.sendline('alter user %s account lock;' % username)
                sqlplus.expect('SQL>')
                sqlplus.sendline('spool %s/%s_disconnect.sql;' % (temp_path, username))
                sqlplus.sendline('select \'alter system kill session \'\'\' || sid ||\',\'||serial#||\'\'\' immediate;\' from v$session where username = UPPER(\'%s\');' % username)
                sqlplus.expect('SQL>')
                sqlplus.sendline('spool off')
                sqlplus.expect('SQL>')

                self.replace_invalidate_chars(temp_path, username, 's/SQL>.*//g')
                self.replace_invalidate_chars(temp_path, username, 's/new\s\{3\}.*//g')
                self.replace_invalidate_chars(temp_path, username, 's/old\s\{3\}.*//g')

                sqlplus.sendline('@%s/%s_disconnect.sql;' % (temp_path, username))
                sqlplus.expect('SQL>', timeout=1800)

            elif index == 1:
                log_proxy.info('user[%s] not exists.', username)

            if truncate_file:
                log_proxy.info('=======> Start tables truncate')
                sqlplus.sendline('@%s' % truncate_file)
                sqlplus.expect('SQL>', timeout=1800)
                log_proxy.info('=======> End tables truncate')

            sqlplus.sendline('DROP DIRECTORY %s;' % dump_path_name)
            sqlplus.expect('SQL>', timeout=1800)

            sqlplus.sendline('create directory %s as \'%s\';' % (dump_path_name, temp_path))
            sqlplus.expect('SQL>', timeout=1800)

            sqlplus.sendline('grant read,write on directory %s to %s;' % (dump_path_name, username))
            sqlplus.expect('SQL>', timeout=1800)

            sqlplus.sendline('alter user %s account unlock;' % username)
            sqlplus.expect('SQL>', timeout=1800)

            sqlplus.sendcontrol('d')
            sqlplus.expect('$')

            remap = 'remap_schema=%s:%s remap_tablespace=%s:%s' % (source_username,
                                                                   username,
                                                                   source_tablespace,
                                                                   tablespace)

            # sh = 'impdp %s/%s dumpfile=%s.dmp DIRECTORY=%s %s CONTENT=METADATA_ONLY' % (username,
            sh = 'impdp %s/%s dumpfile=%s.dmp DIRECTORY=%s %s ' % (username,
                                                                  password,
                                                                  params['import_dump_name'],
                                                                  dump_path_name,
                                                                  remap)
            log_proxy.info('======> Start execute oracle import : %s', sh)

            sqlplus.sendline(sh)

            index = sqlplus.expect(['Job "%s"."(.*)" completed with' % username, pexpect.EOF], timeout=None)
            if index == 0:
                log_proxy.info(u'<><><><><><><>oracle数据导入正常结束')
            elif index == 1:
                log_proxy.info(u'<><><><><><><>oracle数据导入shell执行程序数据流结束')
                log_proxy.info(u'<><><><><><><>oracle数据导入异常结束')
                raise TaskExcecuteError('oracle import error.')

            log_proxy.info('======> End execute oracle import ')
            time.sleep(5)
            sqlplus.close()

        except BaseException, e:
            log_proxy.error('=======> ' + e.message)
            raise TaskExcecuteError('execute shell failure, cause: %s.' % e.message)

        log_proxy.info("=======> InitOracleUserTask:Exit execute()")


class UnlockOracleUserTask(Task):

    def __init__(self):
        Task.__init__(self, 'UnlockOracleUserTask')

    def __do_execute__(self, params={'username': None}):
        log_proxy = self.get_log(log)
        log_proxy.info('********************************************************')
        log_proxy.info("=======> UnlockOracleUserTask:Entered execute()")
        username = str(params['username']).upper()

        try:
            sqlplus = pexpect.spawn('su - oracle', timeout=1800)
            sqlplus.logfile = log_proxy
            sqlplus.expect('$')
            sqlplus.sendline('sqlplus / as sysdba')
            sqlplus.expect('SQL>')
            sqlplus.sendline('alter user %s account unlock;' % username)
            sqlplus.expect('SQL>', timeout=1800)

            sqlplus.sendcontrol('d')
            sqlplus.expect('$')
            sqlplus.close()

        except BaseException, e:
            log_proxy.error('=======> ' + e.message)
            raise TaskExcecuteError('execute shell failure, cause: %s.' % e.message)

        log_proxy.info("=======> UnlockOracleUserTask:Exit execute()")


class AfterImportTask(Task):

    def __init__(self):
        Task.__init__(self, 'AfterImportTask')

    def __replace_keyword__(self, params, temp_path, filename):
        log_proxy = self.get_log(log)
        if os.path.isfile(filename):
            log_proxy.info('=====> start replace and copy import after sql file[%s]', filename)
            db_name = params['db_name']
            local_ip = params['local_ip']
            log_proxy.info('=====> local ipaddress: [%s]', local_ip)
            new_filename = temp_path + '/' + os.path.basename(filename)
            tbs = open(filename)
            lines = tbs.readlines()
            fp = open(new_filename, 'w')
            for line in lines:
                if line.find('${dbname}') >= 0:
                    line = line.replace('${dbname}', db_name)
                if line.find('$localIp') >= 0:
                    line = line.replace('$localIp', local_ip)
                fp.write(line)
            fp.close()
            tbs.close()
            log_proxy.info('=====> end replace and copy import after sql file')

            log_proxy.info('=======> Start read&write permissions to the script')
            sh = '/bin/bash -c "chmod 777 %s"' % new_filename
            log_proxy.info('=======> execute shell : %s', sh)
            run(sh, withexitstatus=1, logfile=log_proxy)

            return new_filename
        else:
            return None

    def __do_execute__(self, params={'after_imp_sql_files': None}):
        log_proxy = self.get_log(log)
        log_proxy.info('********************************************************')
        log_proxy.info("=======> AfterImportTask:Entered execute()")

        try:
            temp_path = '%s/%s/afterimp' % (params['temp_path'], params['db_name'])
            sh = 'mkdir -p %s' % temp_path
            log_proxy.info('start execute shell : %s', sh)
            output, status = pexpect.run(sh, withexitstatus=1, timeout=30, logfile=log_proxy)
            log_proxy.info('=======> shell status: %s, output: %s', status, output)
            if status != 0:
                raise TaskExcecuteError('create dir[%s] failure, cause: %s.' % (temp_path, output))

            if 'after_imp_sql_files' in params.keys():
                sqls = params['after_imp_sql_files']
                if Converter.typeof_list_or_set(sqls) and len(sqls) > 0:
                    # log_proxy.info('=======> Start read&write permissions to the script')
                    # for sql in sqls:
                    #     sh = '/bin/bash -c "chmod 777 %s"' % sql
                    #     log_proxy.info('=======> execute shell : %s', sh)
                    #     run(sh, withexitstatus=1, logfile=log_proxy)

                    # log_proxy.info('=======> end read&write permissions to the script')

                    for sql in sqls:
                        sql_file = self.__replace_keyword__(params, temp_path, sql)
                        if sql_file:
                            sqlplus = pexpect.spawn('su - oracle', timeout=10)
                            sqlplus.logfile = log_proxy
                            sqlplus.expect('$')
                            sqlplus.sendline('sqlplus %s/%s' % (params['username'], params['password']))
                            sqlplus.expect('SQL>')
                            log_proxy.info('=====> Start executing SQL script file: %s', sql_file)
                            sqlplus.sendline('@%s;' % sql_file)
                            index = sqlplus.expect(['Disconnected from Oracle Database', pexpect.EOF], timeout=None)
                            if index == 0:
                                log_proxy.info('execute SQL script success')
                            elif index == 1:
                                log_proxy.error('execute SQL failure : %s.' % sql_file)
                                raise TaskExcecuteError('execute SQL failure : %s.' % sql_file)

                            sqlplus.sendcontrol('d')
                            sqlplus.close()
                else:
                    log_proxy.info('=======> There is no need to execute the SQL script file')
            else:
                log_proxy.info('=======> There is no need to execute the SQL script file')

        except BaseException, e:
            log_proxy.error('=======> ' + e.message)
            raise TaskExcecuteError('execute shell failure, cause: %s.' % e.message)

        log_proxy.info("=======> AfterImportTask:Exit execute()")